在第二十天的範例中主執行序完成後,未執行完畢的goroutine會被釋放掉,
所以需要使用time.Sleep()讓主執行序暫停一下,
不過golang提供sync
函式庫可以使用。
sync.WaitGroup是一個同步的工具,可以等待goroutine完成。
Add()
:計數器,goroutine的數量。Done()
:計數器完成,進行減-1。Wait()
:主執行序阻塞,直到所有 goroutine 完成為止。實作參考資料1的範例:
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
wg.Add(2) //兩個goroutine
go func() {
count("oranges")
wg.Done()
}()
go func() {
count("apples")
wg.Done()
}()
count("banana")
wg.Wait()
}
func count(thing string) {
for i := 0; i < 4; i++ {
fmt.Printf("counting %s\n", thing)
}
}
輸出結果:
counting banana
counting banana
counting banana
counting banana
counting apples
counting apples
counting apples
counting apples
counting oranges
counting oranges
counting oranges
counting oranges
如果Add()
大於goroutine
數量會發生Deadlock
範例如下:
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
wg.Add(3) //改為3
go func() {
count("oranges")
wg.Done()
}()
go func() {
count("apples")
wg.Done()
}()
count("banana")
wg.Wait()
}
func count(thing string) {
for i := 0; i < 4; i++ {
fmt.Printf("counting %s\n", thing)
}
}
執行後會出現fatal error: all goroutines are asleep - deadlock!